package com.API.beans;

import com.API.dal.entities.*;
import com.API.dal.providers.CostsProvider;
import com.API.dal.providers.EquipmentsProvider;
import com.API.dal.providers.ProjectProvider;
import org.primefaces.context.RequestContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.API.dal.providers.MaterialsProvider;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;

@Component
@Scope("request")
public class MaterialsBean {

    @Autowired
    EquipmentsProvider materialProvider;
    @Autowired
    ProjectProvider projectProvider;
    @Autowired
    CostsProvider costsProvider;

    List<Equipments> materialsList;
    Equipments equipment;
    Equipments selectedEquipment;
    EquipmentCosts equipmentCosts;
    EquipmentsProjects equipmentsProjects;
    Units unit;
    List<Units> unitsList;
    EquipmentsTypes equipmentsTypes;
    List<EquipmentsTypes> typesList;
    Objects origin;
    Objects destination;

    public MaterialsBean(){
        equipment = new Equipments();
        unit = new Units();
        equipmentsTypes = new EquipmentsTypes();
        equipmentCosts = new EquipmentCosts();
        equipmentCosts.setId(new EquipmentCostsId());
        equipmentsProjects = new EquipmentsProjects(new EquipmentsProjectsId(), new Objects(), new Equipments());

    }

    public Objects getDestination() {
        return destination;
    }

    public void setDestination(Objects destination) {
        this.destination = destination;
    }

    public Objects getOrigin() {
        return origin;
    }

    public void setOrigin(Objects origin) {
        this.origin = origin;
    }

    public EquipmentsProjects getEquipmentsProjects() {
        return equipmentsProjects;
    }

    public void setEquipmentsProjects(EquipmentsProjects equipmentsProjects) {
        this.equipmentsProjects = equipmentsProjects;
    }

    public EquipmentCosts getEquipmentCosts() {
        return equipmentCosts;
    }

    public void setEquipmentCosts(EquipmentCosts equipmentCosts) {
        this.equipmentCosts = equipmentCosts;
    }

    public List<Equipments> getMaterialsList() {
        if (materialsList == null)
            materialsList = materialProvider.getMaterials();
        return materialsList;
    }

    public void setEquipment(Equipments equipment) {
        this.equipment = equipment;
    }

    public void setSelectedEquipment(Equipments selectedEquipment) {
        this.selectedEquipment = selectedEquipment;
    }

    public Equipments getEquipment() {
        return equipment;
    }

    public Equipments getSelectedEquipment() {
        return selectedEquipment;
    }

    public List<String> getCompleteMaterial(String query){
        List<String> strList = new LinkedList<String>();
        for (Equipments eq: materialProvider.getMaterials()){
            String str = eq.getName();
            if (str.startsWith(query) || str.startsWith(query.toLowerCase())
                    || str.startsWith(query.toUpperCase())){
                strList.add(str);
            }
        }

        return strList;
    }

    public List<String> getTypesList() {
        List<String> strList = new LinkedList<String>();
        if (typesList == null)
            typesList = materialProvider.getEquipmentsTypes();
        for (EquipmentsTypes eq: typesList)
            strList.add(eq.getName());
        return strList;
    }

    public Units getUnit() {
        return unit;
    }

    public List<String> getUnitsList() {
        List<String> strList = new LinkedList<String>();
        if (unitsList == null)
            unitsList = materialProvider.getUnits();
        for (Units un : unitsList)
            strList.add(un.getName());
        return strList;
    }

    public EquipmentsTypes getEquipmentsTypes() {
        return equipmentsTypes;
    }

    public void setUnit(Units unit) {
        this.unit = unit;
    }

    public void setEquipmentsTypes(EquipmentsTypes equipmentsTypes) {
        this.equipmentsTypes = equipmentsTypes;
    }

    public String getMaterialType(int material_id){
        EquipmentsTypes et = materialProvider.getEquipmentType(material_id);
        String str = et.getName();
        return str;
    }

    public String getMaterialUnits(int material_id){
        Units un = materialProvider.getEquipmentUnit(material_id);
        String str = un.getName();
        return str;
    }

    public void addMaterial() {
        final RequestContext context = RequestContext.getCurrentInstance();
        context.execute("addMaterialDialog.show()");
    }

    public void saveMaterial(){
        RequestContext context = RequestContext.getCurrentInstance();
        context.update("materialForm");
        unit = materialProvider.getEquipmentUnit(unit.getName());
        equipmentsTypes = materialProvider.getEquipmentType(equipmentsTypes.getName());
        equipment.setEquipmentsTypes(equipmentsTypes);
        equipment.setUnits(unit);
        materialProvider.addMaterial(equipment);
        FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO,
                "Материал добавлен успешно", equipment.getName());
        FacesContext.getCurrentInstance().addMessage(null, msg);
        context.addCallbackParam("saveMaterial", true);
    }

    public void edit(){
        final RequestContext context = RequestContext.getCurrentInstance();
        if (selectedEquipment != null){
            selectedEquipment = materialProvider.getEquipmentById(selectedEquipment.getId());
            context.update("materialForm");
            context.execute("editMaterialDialog.show()");
        }
        else {
            context.update("materialForm");
            FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR,
                    "Ошибка.","Материал не выбран");
            FacesContext.getCurrentInstance().addMessage(null, msg);

        }

    }

    public void saveEdit(){
        RequestContext context = RequestContext.getCurrentInstance();
        context.update("materialForm");
        unit = materialProvider.getEquipmentUnit(unit.getName());
        equipmentsTypes = materialProvider.getEquipmentType(equipmentsTypes.getName());
        selectedEquipment.setEquipmentsTypes(equipmentsTypes);
        selectedEquipment.setUnits(unit);
        materialProvider.updateEquipment(selectedEquipment);
        FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO,
                "Материал отредктирован успешно", equipment.getName());
        FacesContext.getCurrentInstance().addMessage(null, msg);
        context.addCallbackParam("saveEdit", true);

    }

    public void closeEdit(){
        final RequestContext context = RequestContext.getCurrentInstance();
        context.execute("editMaterialDialog.hide()");
    }

    public void coming(){
        final RequestContext context = RequestContext.getCurrentInstance();
        context.execute("comingMaterialDialog.show()");

    }

    public void saveComing(){
        RequestContext context = RequestContext.getCurrentInstance();
        context.update("materialForm");
        equipment = materialProvider.getEquipmentByName(equipment.getName());
        Objects project = projectProvider.getProjectByName(equipmentsProjects.getObjects().getName());
        equipmentsProjects.getId().setProjectId(project.getId());
        equipmentsProjects.getId().setEquipmentId(equipment.getId());
        double sum = equipmentsProjects.getId().getTotal()*equipmentsProjects.getId().getPrice().doubleValue();
        equipmentsProjects.getId().setTotalSum(BigDecimal.valueOf(sum));
        equipmentsProjects.setObjects(project);
        equipmentsProjects.setEquipments(equipment);
        materialProvider.addMaterialProject(equipmentsProjects);
        EquipmentCosts eq = new EquipmentCosts(new EquipmentCostsId(), new Equipments(), new Costs());
        Costs cost = new Costs();
        cost.setCostsTypes(costsProvider.getCostTypeByName("Покупка строительных материалов"));
        cost.setChangeDate(equipmentsProjects.getId().getDeliveryDate());
        cost.setTotal(BigDecimal.valueOf(sum));
        cost.setNotes("Закупка материалов  " + equipment.getName()  + " на проект " + project.getName());
        costsProvider.addCost(cost);
        eq.setCosts(cost);
        eq.setEquipments(equipment);
        eq.getId().setCostId(cost.getId());
        eq.getId().setEquipmentId(equipment.getId());
        materialProvider.addEquipmentCost(eq);
        FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO,
                equipment.getName(), "Поступление материала проведено успешно." );
        FacesContext.getCurrentInstance().addMessage(null, msg);
        context.addCallbackParam("saveComing", true);
    }

    public void closeComing(){
        final RequestContext context = RequestContext.getCurrentInstance();
        context.execute("comingMaterialDialog.hide()");
    }

    public void expense(){
        final RequestContext context = RequestContext.getCurrentInstance();
        context.execute("expenseMaterialDialog.show()");
    }

    public void saveExpense(){
        RequestContext context = RequestContext.getCurrentInstance();
        context.update("materialForm");
        equipment = materialProvider.getEquipmentByName(equipmentsProjects.getEquipments().getName());
        Objects project = projectProvider.getProjectByName(equipmentsProjects.getObjects().getName());
        equipmentsProjects.getId().setPrice(BigDecimal.valueOf(0));
        int total = 0 - equipmentsProjects.getId().getTotal();
        equipmentsProjects.getId().setTotal(total);
        equipmentsProjects.getId().setProjectId(project.getId());
        equipmentsProjects.getId().setEquipmentId(equipment.getId());
        equipmentsProjects.getId().setTotalSum(BigDecimal.valueOf(0));
        equipmentsProjects.setObjects(project);
        equipmentsProjects.setEquipments(equipment);
        materialProvider.addMaterialProject(equipmentsProjects);
        FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO,
                equipment.getName(), "Поступление материала проведено успешно." );
        FacesContext.getCurrentInstance().addMessage(null, msg);
        context.addCallbackParam("saveComing", true);

    }

    public void closeExpense(){
        final RequestContext context = RequestContext.getCurrentInstance();
        context.execute("expenseMaterialDialog.hide()");
    }



}
